<template>
  <div class="page-common">
    <Form class="common-form" label-position="top">
      <FormItem
        :required="item.required"
        :label="item.tooltip ? `${item.desc}(${item.tooltip})` :item.desc"
        v-for="(item,index) of args"
        :key="index"
        :class="{'bool-form-item': item.formEditType === 'bool' }"
      >
        <!-- 输入框string -->
        <AutoComplete
          v-if="item.formEditType === 'string' || !item.formEditType"
          :key="new Date().getTime()"
          :value="item.value"
          @autoBlur="commonChange($event,item.name,index)"
        />

        <!-- 选择框dataSelector / conceptSelector-->
        <template
          v-if="(item.formEditType === 'dataSelector' || item.formEditType === 'conceptSelector')"
        >
          <Select
            v-model="item.value.type"
            @on-change="changeDataSelectType(item,index,true)"
            v-if="item.formEditType === 'dataSelector'"
          >
            <Option v-for="item in typeList" :value="item.value" :key="item.value">{{ item.label }}</Option>
          </Select>
          <Input
            class="data-select"
            :value="item.value.name"
            placeholder="请选择"
            disabled
            v-if="item.formEditType === 'conceptSelector'"
          />
          <Input class="data-select" :value="item.value.id" placeholder="请选择路径" disabled v-else/>
          <i class="iconfont icon-file" @click="changeDataSelectType(item,index)"/>
          <CodeSetting :code="item.value.name"/>
        </template>

        <!-- 数字框int -->
        <InputNumber
          style="width:100%"
          v-if="item.formEditType === 'int'"
          :value="item.value"
          :precision="0"
          placeholder="请输入参数"
          clearable
          @on-change="commonChange($event,item.name,index)"
        />

        <!-- 数字框double -->
        <InputNumber
          style="width:100%"
          v-if="item.formEditType === 'double'"
          :value="item.value"
          :step="0.01"
          placeholder="请输入参数"
          clearable
          @on-change="commonChange($event,item.name,index)"
        />

        <!-- 文件选择 -->
        <template v-if="item.formEditType === 'file'">
          <AutoComplete
            style="width:92%"
            :key="new Date().getTime()"
            :value="item.value"
            @autoBlur="commonChange($event,item.name,index)"
          />
          <i class="iconfont icon-file" @click="argFileHandler(item.value,index)"/>
          <CodeSetting :code="item.value"/>
        </template>

        <!-- 布尔值 -->
        <Checkbox
          v-model="item.value"
          v-if="item.formEditType === 'bool'"
          @on-change="commonChange($event,item.name,index)"
        >{{item.desc}}</Checkbox>

        <!-- 映射 -->
        <template v-if="item.formEditType === 'fieldsMapping'">
          <div class="field-map" v-for="(unit,order) of item.value" :key="order">
            <Input
              style="width:43%"
              v-model.trim="unit.key"
              placeholder="请输入key"
              @on-blur="commonChange($event,item.name,index,order)"
            />
            <Input
              style="width:43%"
              v-model.trim="unit.target"
              placeholder="请输入target"
              @on-blur="commonChange($event,item.name,index,order)"
            />
            <i class="iconfont icon-trash" @click="delMap(item.name,index,order)"></i>
          </div>

          <Button type="primary" size="small" @click="addMap(index)">添加{{item.desc}}</Button>
        </template>

        <!-- 选择框 -->
        <Select
          v-model="item.value"
          v-if="item.formEditType === 'select'"
          @on-change="commonChange($event,item.name,index)"
        >
          <Option
            v-for="unit in item.valueLabels"
            :value="unit.value"
            :key="unit.value"
          >{{ unit.label }}</Option>
        </Select>

        <!-- fieldsSelector -->
        <!-- <template v-if="item.formEditType === 'fieldsSelector'">
          <Button
            type="primary"
            @click="fieldsSelectorHandler(item.value,index)"
          >{{item.value.length > 0 ? `已选择${item.value.length}个字段` : '选择字段'}}</Button>
        </template>-->
      </FormItem>
    </Form>

    <!-- 选择结构数据 -->
    <Modal footer-hide title="选择数据集数据" v-model="dsdataVisible" width="700px">
      <dsdata
        :fileUrl="dataArg"
        :hidePreview="true"
        v-if="dsdataVisible"
        @cancelHandler="dsdataVisible=false"
        @okHandler="dsdataOkHandler"
      />
    </Modal>

    <!-- 选择图谱数据 -->
    <Modal
      footer-hide
      title="选择图谱数据"
      v-model="ceptdataVisible"
      width="800px"
      class="cept-workflow-modal"
    >
      <ceptdata
        :fileUrl="ceptArg"
        :hidePreview="true"
        v-if="ceptdataVisible"
        @cancelHandler="ceptdataVisible=false"
        @okHandler="ceptdataOkHandler"
      />
    </Modal>

    <!-- 参数文件 -->
    <Modal footer-hide title="选择文件" v-model="argfileVisible" width="700px">
      <filedata
        :filePath="argfileValue"
        v-if="argfileVisible"
        @cancelHandler="argfileVisible=false"
        @okHandler="argfileOkHandler"
      />
    </Modal>

    <!-- 选择字段 -->
    <Modal footer-hide title="选择字段" v-model="selectdataVisible" width="700px">
      <select-data
        v-if="selectdataVisible"
        @cancelHandler="selectdataVisible=false"
        @okHandler="selectDataOk"
      />
    </Modal>
  </div>
</template>

<script>
import { wfCode } from 'assets/scripts/code';
import SelectData from '../Common/SelectData';
import Dsdata from '../Common/Dsdata';
import Ceptdata from '../Common/Ceptdata';
import Filedata from '../Common/Filedata';
import AutoComplete from '../Common/AutoComplete';
import CodeSetting from '../Common/CodeSetting';

import { updateCustomNode } from 'http/api/workflow';
import { mapState, mapMutations } from 'vuex';

export default {
  props: ['nodeInfo'],
  components: {
    Dsdata,
    Ceptdata,
    Filedata,
    AutoComplete,
    CodeSetting,
    SelectData
  },
  watch: {
    nodeInfo () {
      this.setNodeInfo();
    }
  },
  computed: {
    ...mapState({
      currentNode: state => state.workflow.currentNode,
      link: state => state.workflow.link,
      node: state => state.workflow.node
    })
  },
  data () {
    return {
      pipelineId: null,
      name: '',
      argValues: {},
      args: null,
      typeList: [
        {
          label: '数据集数据',
          value: 'ds'
        },
        {
          label: '图谱数据',
          value: 'cept'
        }
      ],
      dsdataVisible: false,
      ceptdataVisible: false,
      dataArg: '',
      ceptArg: '',
      currentIndex: null,

      // 参数文件的选择
      argfileValue: '',
      argfileIndex: null,
      argfileVisible: false,

      // 字段选择
      selectdataVisible: false,
      selectdataValue: '',
      selectdataIndex: null
    };
  },
  methods: {
    ...mapMutations(['setNode']),

    // 字段选择
    fieldsSelectorHandler (value, index) {
      this.selectdataVisible = true;
      this.selectdataIndex = index;
      this.selectdataValue = value;
    },

    // 选中字段后
    selectDataOk (fields) {
      let singleArgName = this.args[this.argfileIndex].name;
      this.commonChange(fields, singleArgName, this.argfileIndex);
      this.argfileVisible = false;
    },

    // 添加映射
    addMap (index) {
      let targetArg = this.args[index];
      let value = targetArg.value;
      value.push({ key: '', target: '' });

      this.args.splice(index, 1, targetArg);
    },

    // 删除映射
    delMap (name, index, order) {
      let targetArg = this.args[index];
      let value = targetArg.value;
      let { key, target } = value[order];

      value.splice(order, 1);
      this.args.splice(index, 1, targetArg);
      if (key && target) {
        // 更新前去除空的
        this.argValues[name] = value.filter(item => {
          return item.target && item.key;
        });
        this.argValues[name] = JSON.stringify(this.argValues[name]);
        this.updateNodeInfo();
      }
    },

    // 参数文件选择
    argFileHandler (value, index) {
      this.argfileValue = value;
      this.argfileIndex = index;
      this.argfileVisible = true;
    },

    // 参数文件选择后
    argfileOkHandler (url) {
      let singleArgName = this.args[this.argfileIndex].name;
      this.commonChange(url, singleArgName, this.argfileIndex);
      this.argfileVisible = false;
    },

    // 重置编辑信息
    setNodeInfo () {
      let { name, args, argValues } = this.nodeInfo;
      this.name = name;
      this.args = args;
      this.argValues = argValues ? JSON.parse(argValues) : {};
      if (this.args) {
        this.args.forEach(item => {
          let argValueItem = this.argValues[item.name];
          item.value = argValueItem || item.defaultValue;

          if (
            (item.formEditType === 'dataSelector' ||
              item.formEditType === 'conceptSelector') &&
            !item.value
          ) {
            item.value = {
              id: item.defaultValue ? item.defaultValue : '',
              type: item.formEditType === 'conceptSelector' ? 'cept' : '',
              name: ''
            };
          }

          // 映射
          if (item.formEditType === 'fieldsMapping') {
            try {
              item.value = JSON.parse(item.value);
            } catch (err) {}
          }

          // 布尔值
          if (item.formEditType === 'bool') {
            if (item.value === 'false') {
              item.value = false;
            }
            if (item.value === 'true') {
              item.value = true;
            }
          }

          // 数值转换
          if (item.formEditType === 'int' || item.formEditType === 'double') {
            item.value = item.value ? parseFloat(item.value) : 0;
          }

          // select
          if (item.formEditType === 'select') {
            let values = [];
            item.values.forEach(item => {
              let spaceIndex = item.indexOf('|');
              if (spaceIndex > -1) {
                values.push({
                  label: item.substr(spaceIndex + 1),
                  value: item.substr(0, spaceIndex)
                });
              } else {
                values.push({
                  label: item,
                  value: item
                });
              }
            });
            item.valueLabels = values;
          }

          // 数值转换
          if (item.formEditType === 'int' || item.formEditType === 'double') {
            // item.value =item.value ?  parseFloat(item.value) : 0
          }

          if (!this.argValues[item.name]) {
            this.argValues[item.name] = item.value;
          }
        });
      }
    },

    /**
     * 修改数据
     * @param index arg对应的下标
     * @param order value对应的小标
     */
    commonChange (e, name, index, order) {
      let nodeName = e.target && e.target.nodeName;
      let value;
      if (nodeName === 'INPUT' || nodeName === 'TEXTAREA') {
        value = e.target.value;
        value = value.trim();
        if (value === '') {
          return;
        }
      } else {
        value = e;
      }
      // 改变数组的值--map
      if (order !== undefined) {
        // 只有对应的2个都有值的时候才更新
        let argValue = this.args[index].value;
        let orderItem = argValue[order];
        if (orderItem.target && orderItem.key) {
          // 更新前去除空的
          this.argValues[name] = argValue.filter(item => {
            return item.target && item.key;
          });
          this.argValues[name] = JSON.stringify(this.argValues[name]);
          this.updateNodeInfo();
        }
      } else {
        // 改变单个参数的值
        this.argValues[name] = value;
        this.args[index].value = value;
        this.updateNodeInfo();
      }
    },

    // 节点更新
    updateNodeInfo () {
      let { x, y, id } = this.currentNode;

      let param = {
        id: id,
        location: { x, y },
        pipeline: {
          id: this.pipelineId
        },
        argValues: JSON.stringify(this.argValues)
      };

      let wires = [];
      this.link.forEach(item => {
        let { start, end, srcIndex, desIndex } = item;
        if (start === id) {
          wires.push({
            srcId: start,
            desId: end,
            desIndex: desIndex || 0,
            srcIndex: srcIndex || 0
          });
        }
      });

      param.wires = wires;
      param.pipelineTaskNodeType = wfCode.COMMON;

      // 先改数据
      this.node[id] = Object.assign({}, this.node[id], param);
      this.setNode(this.node);

      updateCustomNode(param).then(res => {
        this.node[id] = Object.assign({}, this.node[id], res.data);
        this.setNode(this.node);
      });
    },

    // 选择数据的更改
    changeDataSelectType (item, index, boolean) {
      if (boolean) {
        // 值清空
        this.args[index].value.id = '';
        this.argValues[item.name].id = '';
      }

      let { value } = item;
      let { type, id } = value;

      // 数据结构
      if (type === 'ds') {
        this.dsdataVisible = true;
        this.dataArg = boolean ? '' : id;
      }

      if (type === 'cept') {
        this.ceptdataVisible = true;
        this.ceptArg = boolean ? '' : id;
      }

      this.currentIndex = index;
    },

    // 设置参数的值
    setArg (id, name) {
      let index = this.currentIndex;
      let optArg = this.args[index];

      this.args[index].value.id = id;
      this.args[index].value.name = name;

      this.argValues[optArg.name].id = id;
      this.argValues[optArg.name].name = name;
    },

    // 选择数据
    dsdataOkHandler ({ id, name }) {
      this.setArg(id, name);
      this.dsdataVisible = false;
      this.updateNodeInfo();
    },

    // 图谱数据
    ceptdataOkHandler ({ id, name }) {
      this.setArg(id, name);
      this.ceptdataVisible = false;
      this.updateNodeInfo();
    }
  },
  mounted () {
    this.pipelineId = this.$route.query.pipelineId;

    // 节点编辑信息
    if (this.nodeInfo) {
      this.setNodeInfo();
    }
  }
};
</script>

<style rel="stylesheet/less" lang="less" scoped>
.page-common {
  .common-form {
    padding-top: 20px;
    padding-left: 20px;
    padding-right: 20px;
    min-height: 450px;
  }

  .data-select {
    width: 92%;
    margin-top: 5px;
  }
  .icon-file {
    position: relative;
    top: 5px;
    color: #888888;
    font-size: 16px;
    left: 5px;
    cursor: pointer;
  }
  .field-map {
    .add-map {
      font-size: 16px;
      text-align: center;
    }
    .icon-trash {
      cursor: pointer;
    }
  }
}
</style>

<style lang="less">
.bool-form-item .ivu-form-item-label {
  display: none !important;
}
</style>
